#include "player.h"
#include "main.h"
#include "map.h"
#include "resources.h"

void player_init(Player *p)
{
	p->skill.level = 1;
	p->skill.max_hp = PLAYER_HPINIT;
	
	p->pos.dir = DIR_DOWN;
	p->pos.x = 4;
	p->pos.y = 4;
	p->pos.z = 0;
	
	p->action = no_action;
	p->want_action = no_action;
	p->hp = p->skill.max_hp;
	p->checkpoint = (coord_t) {0,0,0};
	
	p->inv.slot[0] = 0;
	p->inv.slot[1] = 0;
	p->inv.slot[2] = 0;
	p->inv.slot[3] = 0;
	p->inv.slot[4] = 0;
	
	p->anim.frame = 0;
}

/*
 * Returns the pixel-precise coordinates of the player
 * on the map (not the screen!). These coordinates point
 * to the center of the tile where the player is currently
 * standing, or if they are moving between the tiles, 
 * adjusted accordingly.
 */
coord_t player_pxpos (Player *p)
{
	coord_t c = { 
		p->pos.x*TILE_SIZE + TILE_SIZE/2,
		p->pos.y*TILE_SIZE + TILE_SIZE/2,
		p->pos.z };
	
	if (p->action.type == ACTION_MOVE) {
		int px = TILE_SIZE * p->action.cooldown / COOLDOWN_MOVE;
		switch (p->action.dir) {
		case DIR_UP:    c.y += px; break;
		case DIR_RIGHT: c.x -= px; break;
		case DIR_DOWN:  c.y -= px; break;
		case DIR_LEFT:  c.x += px; break;
		default: assert(0);
		}
	}

	return c;
}

void player_display(Player *p, int map_offsetx, int map_offsety)
{
	// set target draw coords to top left of sprite
	coord_t pos = player_pxpos(p);
	pos.x += map_offsetx - SPRITE_W/2;
	pos.y += map_offsety - SPRITE_H;
	
	// source draw coords (on sprite sheet)
	int   px_x,   px_y; // pixel offset
	int tile_x, tile_y; // added to px coords
	int  bmp_w,  bmp_h;
	px_x = px_y = tile_x = tile_y = bmp_w = bmp_h = 0;
	
	switch (p->pos.dir) {
		default:
		case DIR_DOWN : tile_y = 0; break;
		case DIR_UP   : tile_y = 1; break;
		case DIR_LEFT : tile_y = 2; break;
		case DIR_RIGHT: tile_y = 3; break;
	}
	
	switch (p->action.type) {
		default:
		case ACTION_NONE:
		case ACTION_MOVE:
		case ACTION_HALT:
		case ACTION_TRAVERSE:
		case ACTION_RESPAWN:
			tile_x = p->anim.frame % 8;
			px_x = 0;
			px_y = 0;
			bmp_w = 16;
			bmp_h = 24;
			break;
			
		case ACTION_ATTACK_CLOSE:
		case ACTION_ATTACK_RANGE:
			tile_x = p->anim.frame % 3;
			px_x = 0;
			px_y = 24*5;
			bmp_w = bmp_h = 64;
			pos.x += SPRITE_SIZE/2 - 32;
			pos.y += SPRITE_SIZE/2 - 24;
			break;

		case ACTION_DIE:
			tile_y = 0; // DIE always has the char looking down
			tile_x = 4 + MIN (p->anim.frame, 11);
			px_x = 0;
			px_y = 4*24;
			bmp_w = 16;
			bmp_h = 24;
			break;
	}
	
	masked_blit (bmp.player, buffer, 
	             px_x + tile_x * bmp_w, px_y + tile_y * bmp_h,
	             pos.x, pos.y, bmp_w, bmp_h);
}
